import InputNode from "@/pages/admin/test/flow/components/InputNode.tsx";
import Sidebar, {SidebarDemo1} from "@/pages/admin/test/flow/components/Sidebar.tsx";
import TextNode from "@/pages/admin/test/flow/components/TextNode.tsx";
import {DnDProvider, useDnD} from "@/pages/admin/test/flow/DnDContext.tsx";
import {useAppSelector} from "@/store/store.ts";
import JsonView from "@uiw/react-json-view";
import {darkTheme} from "@uiw/react-json-view/dark";
import {
    addEdge,
    Background,
    BackgroundVariant,
    Connection,
    NodeTypes,
    ReactFlow,
    ReactFlowProvider,
    useEdgesState,
    useNodesState,
    useReactFlow,
    Viewport
} from "@xyflow/react";
import {Button, Form, Switch, Tag} from "antd";
import React, {DragEvent, useCallback, useState} from "react";
import '@xyflow/react/dist/style.css';
import {BiReset} from "react-icons/bi";


// ReactFlow 自定义节点类型
const nodeTypes = {
    TextNode: TextNode,
    InputNode: InputNode,
};

let id = 0;
const getId = () => `dnd_node_${id++}`;


const initialEdges = [{id: 'e1-2', source: '1', target: '2'}];

const initialNodes = [
    {
        id: getId(),
        type: "TextNode",
        position: {x: 0, y: 500},
        data: {
            label: '6'
        }
    },
]


const Flow = () => {
    const systemState = useAppSelector(state => state.system);

    // ReactFlow 实例
    const reactFlow = useReactFlow();

    // ReactFlow 节点
    const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);

    // ReactFlow 视图配置
    const [viewPort, setViewPort] = useState<Viewport>({
        x: 10,
        y: 10,
        // 默认1倍视图
        zoom: 1,
    })

    const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
    const [snapToGrid, setSnapToGrid] = useState(false)

    const [dndNode] = useDnD();


    // ReactFlow 加载完成
    const onLoad = useCallback(() => {
        reactFlow.fitView().then(r => {
            console.log("[fitView]", r)
        })
    }, [reactFlow]);

    // ReactFlow 节点连接
    const onConnect = useCallback(
        (params: Connection) => setEdges((eds) => addEdge(params, eds)),
        [],
    );

    // ReactFlow 拖入元素
    const onDragOver = useCallback((event: DragEvent) => {
        event.preventDefault();
        event.dataTransfer.dropEffect = 'move';
    }, []);

    // ReactFlow 放置元素
    const onDrop = useCallback(
        (event: React.MouseEvent) => {
            event.preventDefault();

            if (!dndNode) {
                return;
            }

            // 获取拖拽节点相对画板内的位置
            const position = reactFlow.screenToFlowPosition({
                x: event.clientX - 200,
                y: event.clientY,
            });

            console.log("[type]", dndNode)

            // 创建新节点
            const newNode = {
                id: getId(),
                type: dndNode.type,
                position,
                data: {label: `${dndNode} node`},
            };

            setNodes((nds) => nds.concat(newNode));
        },

        [reactFlow.screenToFlowPosition, dndNode],
    );


    return (
        <div className="wrapper min-h-full flex flex-col pb-4 pr-10">
            <div className="p-2 border-l-2 border-l-blue-600 mb-5 mt-5">
                官网地址: <a className={"text-blue-600"} href={""}>https://reactflow.dev/</a>
            </div>
            <Form layout={"inline"} className={"p-4"}>
                <Form.Item label={"对齐网格"}>
                    <Switch value={snapToGrid} onChange={v => setSnapToGrid(v)}/>
                </Form.Item>
                <Form.Item>
                    <Button icon={<BiReset/>} onClick={() => {
                        setNodes(initialNodes)
                    }}>Reset Node</Button>
                </Form.Item>
            </Form>
            <div className={"flex flex-row h-full gap-2"}>
                <Sidebar/>
                <div className={"w-full h-[800px] relative"}>
                    <ReactFlow
                        colorMode={systemState.theme}
                        nodes={nodes.map((node) => ({
                            ...node,
                            data: {
                                ...node.data,
                                setNodes
                            },
                        }))}
                        edges={edges}
                        onNodesChange={onNodesChange}
                        onEdgesChange={onEdgesChange}
                        onConnect={onConnect}
                        onInit={onLoad}
                        nodeTypes={nodeTypes as unknown as NodeTypes}
                        snapToGrid={snapToGrid}
                        onDrop={onDrop}
                        onDragOver={onDragOver}
                        onViewportChange={(viewport) => setViewPort(viewport)}
                        defaultViewport={viewPort}
                    >
                        <Background
                            // 点颜色
                            color={"var(--icon-color)"}
                            // 点样式
                            variant={BackgroundVariant.Dots}
                            // 点间距
                            gap={14}
                            // 单个元素的尺寸
                            size={1}
                        />

                    </ReactFlow>
                    <SidebarDemo1/>
                </div>
            </div>

            <div className={"flex flex-col gap-2 h-[400px]"}>
                <Tag style={{width: "fit-content"}} color={"blue"}>nodes</Tag>
                <JsonView value={nodes} style={{...darkTheme, height: "100%", overflow: "scroll"}}/>
            </div>

            <div className={"flex flex-col gap-2 h-[400px]"}>
                <Tag style={{width: "fit-content"}} color={"blue"}>edges</Tag>
                <JsonView value={edges} style={{...darkTheme, height: "100%", overflow: "scroll"}}/>
            </div>

            <div className={"flex flex-col gap-2 h-[400px]"}>
                <Tag style={{width: "fit-content"}} color={"blue"}>viewport</Tag>
                <JsonView value={viewPort} style={{...darkTheme, height: "100%", overflow: "scroll"}}/>
            </div>
        </div>
    );
};

// eslint-disable-next-line react-refresh/only-export-components
export default () => (
    <ReactFlowProvider>
        <DnDProvider>
            <Flow/>
        </DnDProvider>
    </ReactFlowProvider>
)
